﻿using System;
using System.Collections.Generic;
using BlobNet.Base.Collections.List;
using BlobNet.Base.DataProviders;
using BlobNet.Base.Interfaces;
using BlobNet.Base.Storage;
using BlobNet.TestsCommon.UnitTests.Dummy;
using BlobNet.TestsCommon.Utils;
using NUnit.Framework;
using Rhino.Mocks;
using Rhino.Mocks.Impl;

namespace BlobNet.Base.Tests.UnitTests.CustomCollectionsTests
{
    [TestFixture]
    [Category("Unit Tests")]
    public class BlobPartsPersistentListTests
    {
        [TestFixtureSetUp]
        public void StartFixture()
        {
            RhinoMocks.Logger = new TextWriterExpectationLogger(Console.Out);
        }

        [Test]
        public void Can_AddItem()
        {
            IStorageManager memPersistor;
            IStorageManagerFactory factory = TestsHelper.GetStubFactory(out memPersistor);
            memPersistor.Stub(x => x.CanDettach()).Return(true);

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();

            dataProvider.Stub(
                x =>
                x.AddEntityToCollection(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything,
                                        Arg<int>.Is.Anything, Arg<string>.Is.Anything, Arg<Guid>.Is.Anything));

            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(0);

            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            
            var dummy1 = new DummyBlobPart(blobDomain, factory) {Name = "O1"};

            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, Guid.NewGuid());
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI

            target.Add(dummy1);
            dataProvider.AssertWasCalled(
                x =>
                x.AddEntityToCollection(blobDomain.EntityId, target.EntityId, 0,
                                        typeof (DummyBlobPart).ToString(), dummy1.EntityId));
        }

        [Test]
        public void Can_AddRange()
        {
            IStorageManager memSt, dbSt;
            IStorageManagerFactory factory = TestsHelper.GetStubFactory(out memSt, out dbSt);
            memSt.Stub(x => x.CanDettach()).Return(true);


            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            dataProvider.Stub(
                x =>
                x.AddEntityToCollection(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything,
                                        Arg<int>.Is.Anything, Arg<string>.Is.Anything, Arg<DummyBlobPart>.Is.Anything));

            int count = 0;
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(count++);
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            Guid collectionId = Guid.NewGuid();
            var dummy1 = new DummyBlobPart(blobDomain, factory) {Name = "O1"};
            var dummy2 = new DummyBlobPart(blobDomain, factory) {Name = "O2"};

            IEnumerable<DummyBlobPart> source = new List<DummyBlobPart>(2) {dummy1, dummy2};

            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, collectionId);
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            
            target.AddRange(source);

            dataProvider.AssertWasCalled(
                x =>
                x.AddEntityToCollection(blobDomain.EntityId, target.EntityId, 0,
                                        typeof (DummyBlobPart).ToString(), dummy1.EntityId));
            dataProvider.AssertWasCalled(
                x =>
                x.AddEntityToCollection(blobDomain.EntityId, target.EntityId, 1,
                                        typeof (DummyBlobPart).ToString(), dummy2.EntityId));
        }

        [Test]
        public void Can_Clear()
        {
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(1);
            dataProvider.Stub(x => x.RemoveCollection(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything));
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, Guid.NewGuid());

            target.Clear();

            //dataProvider.AssertWasCalled(x => x.GetCollectionCount(blobDomain.EntityId, target.EntityId));
            dataProvider.AssertWasCalled(x => x.RemoveCollection(blobDomain.EntityId, target.EntityId));
        }

        [Test]
        public void Can_Clear_Empty()
        {
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(0);
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, Guid.NewGuid());

            target.Clear();

            dataProvider.AssertWasCalled(x => x.GetCollectionCount(blobDomain.EntityId, target.EntityId),
                                           options => options.Repeat.AtLeastOnce());
        }

        [Test]
        public void Can_Create_BlobPartList_From_IEnumerable()
        {
            IStorageManager memSt, dbSt;
            IStorageManagerFactory factory = TestsHelper.GetStubFactory(out memSt, out dbSt);
            memSt.Stub(x => x.CanDettach()).Return(true);

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            dataProvider.Stub(
                x =>
                x.AddEntityToCollection(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything,
                                        Arg<int>.Is.Anything, Arg<string>.Is.Anything, Arg<DummyBlobPart>.Is.Anything));
            int count = 0;
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(count++);
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            Guid collectionId = Guid.NewGuid();
            var dummy1 = new DummyBlobPart(blobDomain, factory) {Name = "O1"};
            var dummy2 = new DummyBlobPart(blobDomain, factory) {Name = "O2"};

            IEnumerable<DummyBlobPart> source = new List<DummyBlobPart>(2) {dummy1, dummy2};
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI

            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, collectionId, source);

            dataProvider.AssertWasCalled(
                x =>
                x.AddEntityToCollection(blobDomain.EntityId, target.EntityId, 0,
                                        typeof (DummyBlobPart).ToString(), dummy1.EntityId));
            dataProvider.AssertWasCalled(
                x =>
                x.AddEntityToCollection(blobDomain.EntityId, target.EntityId, 1,
                                        typeof (DummyBlobPart).ToString(), dummy2.EntityId));
        }

        [Test]
        public void Can_Create_BlobList()
        {
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            IDataProvider dataProvider = TestsHelper.GetStubDataProvider();

            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(1);
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            Assert.DoesNotThrow(
                () => new BlobPartsPersistentList<DummyBlobPart>(blobDomain, Guid.NewGuid()));
        }

        [Test]
        public void Can_Create_BlobList_With_Explicit_Id()
        {
            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(1);
            dataProvider.Stub(x => x.RemoveCollection(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything));
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            Guid id = Guid.NewGuid();
            Assert.DoesNotThrow(
                () =>
                new BlobPartsPersistentList<DummyBlobPart>(TestsHelper.GetDummyBlobDomain(), id));
        }


        [Test]
        public void Can_GetByIndexer()
        {
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            IStorageManager memProvider;
            IStorageManager dbProvider;
            IStorageManagerFactory shStorageFactory = TestsHelper.GetStubFactory(out memProvider, out dbProvider);
            memProvider.Stub(x => x.CanDettach()).Return(true);
            dbProvider.Stub(x => x.CanDettach()).Return(true);
            var expected = new DummyBlobPart(blobDomain, shStorageFactory) {Name = "O1"};

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, Guid.NewGuid());

            dataProvider.Stub(
                x =>
                x.RetrieveListItem(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything, Arg<int>.Is.Anything))
                .Return(new TupleList(0, target.EntityId, expected.GetType().FullName, expected.EntityId));
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(1);

            DummyBlobPart actual = target[0];

            Assert.IsTrue(actual.EntityId == expected.EntityId);
            dataProvider.AssertWasCalled(
                x => x.RetrieveListItem(blobDomain.EntityId, target.EntityId, 0));
        }

        [Test]
        public void Can_GetRange()
        {
        }

        [Test]
        public void Can_Get_Contains_Value_WhenFalse()
        {
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            IStorageManager memProvider;
            IStorageManager dbProvider;
            IStorageManagerFactory shStorageFactory = TestsHelper.GetStubFactory(out memProvider, out dbProvider);
            memProvider.Stub(x => x.CanDettach()).Return(true);
            dbProvider.Stub(x => x.CanDettach()).Return(true);

            var dummyBlobPart = new DummyBlobPart(blobDomain, shStorageFactory);

            Guid collectionId = Guid.NewGuid();

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            dataProvider.Stub(
                x =>
                x.RetrieveListItem(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything,
                                   Arg<Guid>.Is.Anything)).Return(null);
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, collectionId);

            bool contains = target.Contains(dummyBlobPart);

            Assert.IsFalse(contains);
            dataProvider.AssertWasCalled(
                x =>
                x.RetrieveListItem(blobDomain.EntityId, target.EntityId,
                                   dummyBlobPart.EntityId));
        }

        [Test]
        public void Can_Get_Contains_Value_WhenTrue()
        {
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            IStorageManager memProvider;
            IStorageManager dbProvider;
            IStorageManagerFactory shStorageFactory = TestsHelper.GetStubFactory(out memProvider, out dbProvider);
            memProvider.Stub(x => x.CanDettach()).Return(true);
            dbProvider.Stub(x => x.CanDettach()).Return(true);

            var dummyBlobPart = new DummyBlobPart(blobDomain, shStorageFactory);

            Guid collectionId = Guid.NewGuid();
            Guid entityId = dummyBlobPart.EntityId;
            string typeParam = dummyBlobPart.GetType().ToString();

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            var expected = new TupleList(2, collectionId, typeParam, null);
            dataProvider.Stub(
                x =>
                x.RetrieveListItem(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything,
                                   Arg<Guid>.Is.Anything)).Return(expected);

            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, collectionId);

            bool contains = target.Contains(dummyBlobPart);

            Assert.IsTrue(contains);
            dataProvider.AssertWasCalled(
                x =>
                x.RetrieveListItem(blobDomain.EntityId, target.EntityId,
                                   dummyBlobPart.EntityId));
        }

        [Test]
        [Ignore]
        public void Can_Get_GenericEnumerator()
        {
            Assert.Inconclusive();
        }

        [Test]
        public void Can_Get_IndexOf()
        {
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            IStorageManager memProvider;
            IStorageManager dbProvider;
            IStorageManagerFactory shStorageFactory = TestsHelper.GetStubFactory(out memProvider, out dbProvider);
            memProvider.Stub(x => x.CanDettach()).Return(true);
            dbProvider.Stub(x => x.CanDettach()).Return(true);

            var dummyBlobPart = new DummyBlobPart(blobDomain, shStorageFactory);

            Guid collectionId = Guid.NewGuid();
            Guid entityId = dummyBlobPart.EntityId;
            string typeParam = dummyBlobPart.GetType().ToString();

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            var expected = new TupleList(2, collectionId, typeParam, entityId);
            dataProvider.Stub(
                x =>
                x.RetrieveListItem(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything,
                                   Arg<Guid>.Is.Anything)).Return(expected);

            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, collectionId);

            int actual = target.IndexOf(dummyBlobPart);

            Assert.IsTrue(actual == expected.Position);
            dataProvider.AssertWasCalled(
                x =>
                x.RetrieveListItem(blobDomain.EntityId, target.EntityId,
                                   dummyBlobPart.EntityId));
        }

        [Test]
        public void Can_Get_IndexOf_When_NotFound()
        {
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            IStorageManager memProvider;
            IStorageManager dbProvider;
            IStorageManagerFactory shStorageFactory = TestsHelper.GetStubFactory(out memProvider, out dbProvider);
            memProvider.Stub(x => x.CanDettach()).Return(true);
            dbProvider.Stub(x => x.CanDettach()).Return(true);
            var dummyBlobPart = new DummyBlobPart(blobDomain, shStorageFactory);

            Guid collectionId = Guid.NewGuid();

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            dataProvider.Stub(
                x =>
                x.RetrieveListItem(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything,
                                   Arg<Guid>.Is.Anything)).Return(null);

            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, collectionId);

            int actual = target.IndexOf(dummyBlobPart);

            Assert.IsTrue(actual == -1);
            dataProvider.AssertWasCalled(
                x =>
                x.RetrieveListItem(blobDomain.EntityId, target.EntityId,
                                   dummyBlobPart.EntityId));
        }

        [Test]
        [Ignore]
        public void Can_Get_NonGenericEnumerator()
        {
            Assert.Inconclusive();
        }

        [Test]
        public void Can_Insert()
        {
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            IStorageManager memProvider;
            IStorageManager dbProvider;
            IStorageManagerFactory shStorageFactory = TestsHelper.GetStubFactory(out memProvider, out dbProvider);
            memProvider.Stub(x => x.CanDettach()).Return(true);
            dbProvider.Stub(x => x.CanDettach()).Return(true);
            var dummyBlobPart = new DummyBlobPart(blobDomain, shStorageFactory);

            Guid collectionId = Guid.NewGuid();
            string typeParam = dummyBlobPart.GetType().ToString();

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            int position = 10;
            dataProvider.Stub(
                x =>
                x.AddEntityToCollection(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything,
                                        Arg<int>.Is.Anything, Arg<string>.Is.Anything, Arg<DummyBlobPart>.Is.Anything));
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(11);
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, collectionId);

            target.Insert(position, dummyBlobPart);

            dataProvider.AssertWasCalled(
                x =>
                x.AddEntityToCollection(blobDomain.EntityId, target.EntityId, position,
                                        typeParam, dummyBlobPart.EntityId));
        }

        [Test]
        public void Can_InsertRange()
        {
            IStorageManager memSt, dbSt;
            IStorageManagerFactory factory = TestsHelper.GetStubFactory(out memSt, out dbSt);
            memSt.Stub(x => x.CanDettach()).Return(true);

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            dataProvider.Stub(
                x =>
                x.AddEntityToCollection(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything,
                                        Arg<int>.Is.Anything, Arg<string>.Is.Anything, Arg<object>.Is.Anything));
            int count = 10;
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(count++);
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            Guid collectionId = Guid.NewGuid();
            var dummy1 = new DummyBlobPart(blobDomain, factory) {Name = "O1"};
            var dummy2 = new DummyBlobPart(blobDomain, factory) {Name = "O2"};

            IEnumerable<DummyBlobPart> source = new List<DummyBlobPart>(2) {dummy1, dummy2};

            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, collectionId);
            target.InsertRange(1, source);

            dataProvider.AssertWasCalled(
                x =>
                x.AddEntityToCollection(blobDomain.EntityId, target.EntityId, 1,
                                        typeof (DummyBlobPart).ToString(), dummy1.EntityId));
            dataProvider.AssertWasCalled(
                x =>
                x.AddEntityToCollection(blobDomain.EntityId, target.EntityId, 2,
                                        typeof (DummyBlobPart).ToString(), dummy2.EntityId));
        }

        [Test]
        public void Can_Remove_At()
        {
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            Guid collectionId = Guid.NewGuid();

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            int position = 10;

            dataProvider.Stub(
                x =>
                x.RemoveEntityFromCollection(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything, Arg<int>.Is.Equal(position)));
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(11);
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, collectionId);

            target.RemoveAt(position);

            dataProvider.AssertWasCalled(
                x => x.RemoveEntityFromCollection(blobDomain.EntityId, target.EntityId, position));
        }

        [Test]
        public void Can_Remove_WhenExisting()
        {
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            IStorageManager memProvider;
            IStorageManager dbProvider;
            IStorageManagerFactory shStorageFactory = TestsHelper.GetStubFactory(out memProvider, out dbProvider);
            memProvider.Stub(x => x.CanDettach()).Return(true);
            dbProvider.Stub(x => x.CanDettach()).Return(true);
            var dummyBlobPart = new DummyBlobPart(blobDomain, shStorageFactory);


            Guid collectionId = Guid.NewGuid();

            string typeParam = dummyBlobPart.GetType().ToString();

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            int position = 10;
            var expected = new TupleList(position, collectionId,
                                         typeParam, dummyBlobPart.EntityId);

            dataProvider.Stub(
                x =>
                x.RetrieveListItem(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything,
                                   Arg<Guid>.Is.Equal(dummyBlobPart.EntityId))).Return(expected);
            dataProvider.Stub(
                x =>
                x.RemoveEntityFromCollection(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything, Arg<int>.Is.Equal(position)));
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(11);
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, collectionId);

            bool resp = target.Remove(dummyBlobPart);

            Assert.IsTrue(resp);
            dataProvider.AssertWasCalled(
                x => x.RemoveEntityFromCollection(blobDomain.EntityId, target.EntityId, position));
        }

        [Test]
        public void Can_Remove_WhenNotExisting()
        {
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            IStorageManager memProvider;
            IStorageManager dbProvider;
            IStorageManagerFactory shStorageFactory = TestsHelper.GetStubFactory(out memProvider, out dbProvider);
            memProvider.Stub(x => x.CanDettach()).Return(true);
            dbProvider.Stub(x => x.CanDettach()).Return(true);

            var dummyBlobPart = new DummyBlobPart(blobDomain, shStorageFactory);

            Guid collectionId = Guid.NewGuid();

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            int position = 10;

            dataProvider.Stub(
                x =>
                x.RetrieveListItem(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything,
                                   Arg<Guid>.Is.Equal(dummyBlobPart.EntityId))).Return(null);
            dataProvider.Stub(
                x =>
                x.RemoveEntityFromCollection(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything, Arg<int>.Is.Equal(position)));
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(11);
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, collectionId);

            bool resp = target.Remove(dummyBlobPart);

            Assert.IsFalse(resp);
            dataProvider.AssertWasNotCalled(
                x => x.RemoveEntityFromCollection(blobDomain.EntityId, target.EntityId, position));
        }

        [Test]
        public void Can_SetByIndexer()
        {
            IStorageManager memPersistor;
            IStorageManagerFactory factory = TestsHelper.GetStubFactory(out memPersistor);
            memPersistor.Stub(x => x.CanDettach()).Return(true);

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            dataProvider.Stub(
                x =>
                x.AddEntityToCollection(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything,
                                        Arg<int>.Is.Anything, Arg<string>.Is.Anything, Arg<object>.Is.Anything));
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(1);

            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            var dummy1 = new DummyBlobPart(blobDomain, factory) {Name = "O1"};
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, Guid.NewGuid());

            target[0] = dummy1;
            dataProvider.AssertWasCalled(
                x =>
                x.AddEntityToCollection(blobDomain.EntityId, target.EntityId, 0,
                                        typeof (DummyBlobPart).ToString(), dummy1.EntityId));
        }

        [Test]
        [Ignore]
        public void Can_Set_BlobPart_In_two_Lists()
        {
        }

        [Test]
        public void Cant_GetByIndexer_OutBoundaries()
        {
            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            dataProvider.Stub(
                x =>
                x.AddEntityToCollection(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything,
                                        Arg<int>.Is.Anything, Arg<string>.Is.Anything, Arg<object>.Is.Anything));
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(0);

            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            DummyBlobPart actual = null;

            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, Guid.NewGuid());
            Assert.Throws(typeof (ArgumentOutOfRangeException), () => actual = target[0]);
        }

        [Test]
        public void Cant_Remove_At_When_Index_Out_Boundaries()
        {
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            Guid collectionId = Guid.NewGuid();

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            int position = 10;

            dataProvider.Stub(
                x =>
                x.RemoveEntityFromCollection(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything, Arg<int>.Is.Equal(position)));
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(10);
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, collectionId);

            Assert.Throws(typeof (ArgumentOutOfRangeException), () => target.RemoveAt(position));

            dataProvider.AssertWasNotCalled(
                x => x.RemoveEntityFromCollection(blobDomain.EntityId, target.EntityId, position));
        }

        [Test]
        public void Cant_SetByIndexer_OutBoundaries()
        {
            IStorageManager memProvider;
            IStorageManager dbProvider;
            IStorageManagerFactory factory = TestsHelper.GetStubFactory(out memProvider, out dbProvider);
            memProvider.Stub(x => x.CanDettach()).Return(true);
            dbProvider.Stub(x => x.CanDettach()).Return(true);

            var dataProvider = MockRepository.GenerateStub<IDataProvider>();
            dataProvider.Stub(
                x =>
                x.AddEntityToCollection(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything,
                                        Arg<int>.Is.Anything, Arg<string>.Is.Anything, Arg<object>.Is.Anything));
            dataProvider.Stub(x => x.GetCollectionCount(Arg<Guid>.Is.Anything, Arg<Guid>.Is.Anything)).Return(0);
            DataProviderFactory.Provider = dataProvider;//TODO: MUST BE CHANGED WHEN USING DI
            BlobDomain blobDomain = TestsHelper.GetDummyBlobDomain();
            var dummy1 = new DummyBlobPart(blobDomain, factory) {Name = "O1"};

            var target = new BlobPartsPersistentList<DummyBlobPart>(blobDomain, Guid.NewGuid());

            Assert.Throws(typeof (ArgumentOutOfRangeException), () => target[0] = dummy1);
        }

        [Test]
        [Ignore]
        public void Cant_Set_BlobPart_In_List_When_Already_Attached_To_Another_BlobDomain()
        {
            Assert.Inconclusive();
        }

        [Test]
        [Ignore]
        public void TestEnumerator()
        {
            Assert.Inconclusive();
        }
       
    }
}